package configclass

import (
	"fmt"
	"sync"
)

type MysqlSource struct {
	Target            string `json:"target"`
	DbPrefix          string `json:"db_prefix"`
	TablePrefix       string `json:"table_prefix"`
	DbQuantity        int    `json:"db_quantity"`
	TableQuantity     int    `json:"table_quantity"`
	PageSize          string `json:"page_size"`
	IncrementDatetime string `json:"increment_datetime"`
	Sql               string `json:"sql"`
}

type MysqlDestination struct {
	Target string `json:"target"`
	Sql    string `json:"sql"`
}

type MysqlConfig struct {
	Status      string           `json:"status"`
	Crontab     string           `json:"crontab"`
	Source      MysqlSource      `json:"source"`
	Destination MysqlDestination `json:"destination"`
}

var (
	once     sync.Once
	instance *ConfigManager
)

// 配置文件扫描进结构体 方便管理配置文件
type ConfigManager struct {
	mu             sync.RWMutex
	mysqlConfigMap map[string]MysqlConfig
}

func GetConfigManager() *ConfigManager {
	once.Do(func() {
		instance = newConfigManager()
	})
	return instance
}

func newConfigManager() *ConfigManager {
	return &ConfigManager{
		mysqlConfigMap: make(map[string]MysqlConfig),
	}
}

// GetAllConfigs 返回所有 MySQL 配置的副本。
// 返回值：
//
//	map[string]MysqlConfig - 当前所有配置的副本，
//	由于返回的是值类型，修改返回的配置不会影响原始配置。
func (cm *ConfigManager) GetAllConfigs() map[string]MysqlConfig {
	cm.mu.RLock()
	defer cm.mu.RUnlock()
	// 返回当前所有配置的副本
	return cm.mysqlConfigMap
}

// SetConfig 设置指定键的 MySQL 配置。
// 返回值：
//
//	无返回值，配置成功后会更新内部的 mysqlConfigMap。
func (cm *ConfigManager) SetConfig(key string, config MysqlConfig) {
	cm.mu.Lock()
	defer cm.mu.Unlock()
	cm.mysqlConfigMap[key] = config
}

// GetConfig 返回指定键的 MySQL 配置及其存在状态。
// 返回值：
//
//	MysqlConfig - 对应键的 MySQL 配置，
//	bool - 如果配置存在，返回 true；否则返回 false。
func (cm *ConfigManager) GetConfig(key string) (MysqlConfig, bool) {
	cm.mu.RLock()
	defer cm.mu.RUnlock()
	config, exists := cm.mysqlConfigMap[key]
	// 返回的是值的副本
	return config, exists
}

// SetIncrementDatetime 设置指定键的 IncrementDatetime 值。
// 返回值：
//
//	bool - 如果成功更新，返回 true；如果配置不存在，返回 false。
func (cm *ConfigManager) SetIncrementDatetime(key, incrementDatetime string) bool {
	cm.mu.Lock()
	defer cm.mu.Unlock()
	if config, exists := cm.mysqlConfigMap[key]; exists {
		config.Source.IncrementDatetime = incrementDatetime
		cm.mysqlConfigMap[key] = config
		return true
	}
	return false
}

// GetIncrementDatetime 返回指定键的 IncrementDatetime 值及其存在状态。
// 返回值：
//
//	string - 对应键的 IncrementDatetime 值，
//	bool - 如果配置存在，返回 true；否则返回 false。
func (cm *ConfigManager) GetIncrementDatetime(key string) (string, bool) {
	cm.mu.RLock()
	defer cm.mu.RUnlock()
	if config, exists := cm.mysqlConfigMap[key]; exists {
		// 返回值类型为值
		return config.Source.IncrementDatetime, true
	}
	return "", false
}

func (cm *ConfigManager) Output() {
	cm.mu.RLock()
	defer cm.mu.RUnlock()
	for key, value := range cm.mysqlConfigMap {
		fmt.Println("---------------MysqlConfigMapOutput---------------")
		fmt.Println("Key:", key)
		fmt.Println("Status:", value.Status)
		fmt.Println("Crontab:", value.Crontab)
		fmt.Println("Source.DbPrefix:", value.Source.DbPrefix)
		fmt.Println("Source.TablePrefix:", value.Source.TablePrefix)
		fmt.Println("Source.DbQuantity:", value.Source.DbQuantity)
		fmt.Println("Source.TableQuantity:", value.Source.TableQuantity)
		fmt.Println("Source.Sql:", value.Source.Sql)
		fmt.Println("Source.IncrementDatetime:", value.Source.IncrementDatetime)
		fmt.Println("Destination.Sql:", value.Destination.Sql)
	}
}
